<script setup lang="ts" name="GoodsSku">
import { GoodsInfo } from "@/types/goods";
import { Spec, SpecValue } from "@/types/goods";
import bwPowerSet from "@/utils/bwPowerSet";

// sku组件的基本使用：
// 1.（必须）传入  商品信息对象=>拥有了启用禁用，选择功能
// 2.（可选）传入  skuId      =>默认回显，默认让一些规格选中
// 3.当全部规格选完的时候，就是确定了一个sku，需要子传父，将skuId传给父
const props = defineProps<{
  goods: GoodsInfo;
  skuId?: string;
}>();
const emit = defineEmits<{
  (e: "changeSku", skuId: string): void;
}>();

const SPLIT_STR = "+";
const changeSelected = (spec: Spec, specValue: SpecValue) => {
  if (specValue.disabled) return;
  if (specValue.selected) {
    // 如果选中了就取消选中
    specValue.selected = false;
  } else {
    // 如果没有选中，则干掉所有，选择自己
    spec.values.forEach((v) => (v.selected = false));
    specValue.selected = true;
  }
  updateDisabledStatus();

  // （1）判断，是否所有可选规格都已经选择
  const selectedArr = getSelectedSpec().filter((item) => item);
  if (selectedArr.length === props.goods.specs.length) {
    // 说明全部选中，将得到的数组，转成字符串，去pathMap中找对应skuId
    const key = selectedArr.join(SPLIT_STR);
    const result = pathMap[key];
    const skuId = result[0]; // 这个skuId，是result中的唯一值
    console.log(skuId);
    emit("changeSku", skuId);
  } else {
    emit("changeSku", "");
  }
};
// 一进入页面，控制启用禁用状态=》需要路径字典
// 基于sku数据，得到路径字典
const getPathMap = () => {
  const pathMap: {
    [key: string]: string[];
  } = {};
  // 1.过滤所有的skus，得到有效的skus（库存>0）
  const skus = props.goods.skus.filter((item) => item.inventory > 0);
  // 2.遍历有效的sku，获取sku的子集，进行处理
  skus.forEach((sku) => {
    // 3.整理数据，整理得到[属性1，属性2，属性3]
    const arr = sku.specs.map((item) => item.valueName);
    // 4.基于整理的属性列表，求子集
    const powerSet = bwPowerSet(arr);
    // 5.遍历子集，将子集数据往pathMap中整理
    // （1）如果筛选条件，不存在，新开一个属性，寸
    // （2）如果筛选条件，已存在，在已有属性上，累加
    console.log("powerSet", powerSet);
    powerSet.forEach((sub) => {
      // 将数组信息，拼合成一个字符串，将来作为键（sku.id作为值）
      const key = sub.join(SPLIT_STR);
      // 判断键在对象中是否存在
      if (key in pathMap) {
        // 已存在，在已有的属性值上累加
        pathMap[key].push(sku.id);
      } else {
        // 不存在，直接新开一个属性，属性值是一个有一项内容的数组
        pathMap[key] = [sku.id];
      }
    });
  });
  return pathMap;
};
// 默认根据父传子，传递的skuId，进行回显，设置选中状态
const initSelectedSpec = () => {
  if (!props.skuId) return;
  const sku = props.goods.skus.find((item) => item.id === props.skuId);
  if (!sku) return;
  // 基于sku.specs，让按钮设置成选中状态
  props.goods.specs.forEach((spec, index) => {
    const text = sku.specs[index].valueName;
    const specValue = spec.values.find((item) => item.name === text);
    specValue!.selected = true;
  });
};

// 1.获取字典路径
const pathMap = getPathMap();

initSelectedSpec();
// 更新启用禁用状态
const updateDisabledStatus = () => {
  const selectArr = getSelectedSpec(); // ['','','中国']
  // 根据路径字典=》更新所有的按钮specValue的状态
  props.goods.specs.forEach((spec, index) => {
    spec.values.forEach((specValue) => {
      // 让当前这个按钮，specValue.name(黑色)和selectArr进行组合
      // 注意：这边尝试组合，判断是否禁用时，需要拷贝一份原数组
      const tempArr = [...selectArr];
      tempArr[index] = specValue.name; // ['黑色','','中国']
      // 得到组合后转成字符串key    '黑色+中国'
      const key = tempArr.filter((item) => item).join(SPLIT_STR);
      if (key in pathMap) {
        specValue.disabled = false;
      } else {
        specValue.disabled = true;
      }
    });
  });
};
// 获取当前的选中状态
const getSelectedSpec = () => {
  // 根据现有的所有按钮，进行遍历，将选中的值，按照下标存入数组
  const arr = ["", "", ""];
  // props.goods.specs.forEach((spec) => {
  //   spec.values.forEach((specValue) => {
  //     console.log(specValue.selected);
  //   });
  // });
  props.goods.specs.forEach((spec, index) => {
    const tempObj = spec.values.find((specValue) => specValue.selected);
    arr[index] = tempObj ? tempObj.name : "";
  });
  return arr;
};
// 2.更新启用禁用状态
updateDisabledStatus();
</script>
<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.name">
      <dt>{{ item.name }}</dt>
      <dd>
        <template v-for="sub in item.values" :key="sub.name">
          <img
            v-if="sub.picture"
            :class="{ selected: sub.selected, disabled: sub.disabled }"
            :src="sub.picture"
            alt=""
            :title="sub.name"
            @click="changeSelected(item, sub)"
          />
          <span
            :class="{ selected: sub.selected, disabled: sub.disabled }"
            v-else
            @click="changeSelected(item, sub)"
            >{{ sub.name }}</span
          >
        </template>
      </dd>
    </dl>
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
